Skip to content

Add try/except/else/finally flowchart support#39

Merged
cdfmlr merged 8 commits intomasterfrom
copilot/review-stale-issues
Feb 28, 2026
Merged

Add try/except/else/finally flowchart support#39
cdfmlr merged 8 commits intomasterfrom
copilot/review-stale-issues

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 28, 2026

Implements complete flowchart generation for all four clauses of a Python try statement. Previously, try statements were not supported; this PR adds a new Try AST node that builds the full exception-handling subgraph:

  • try body → an operation node feeding into an "exception raised?" decision diamond
  • except <Type> → a yes-branch for each handler, chained in order (matched / not matched)
  • else → taken on the no-exception path (after all handlers decline)
  • finally → all paths (handled exception, unhandled exception, no exception) converge here before continuing

When the try body contains multiple statements they are folded into a single OperationNode (using the same astunparse.unparse pattern already used throughout the codebase) so the entire block is correctly scoped under the exception diamond.

try:
    a = setup()
    b = process(a)
    c = finalize(b)
except ValueError:
    handle()
else:
    success()
finally:
    cleanup()

Changes

  • pyflowchart/ast_node.py — new Try AST node class that builds the full exception-handling subgraph (body → exc_cond diamond → handler chain → else → finally); multi-statement bodies are folded into a single OperationNode
  • pyflowchart/node.py — register Try in the node dispatcher
  • test/test.py — comprehensive test suite:
    • test_try_simple — basic try/except
    • test_try_multiline_body — multi-statement body folded into one node
    • test_try_full — all four clauses with two except handlers (except ValueError, except Exception as e), an else, and a finally
    • test_try_in_sequenceprepare() → try block → use(result) (try node connects correctly in a sequence)
    • test_try_in_looptry/except nested inside a for loop (back-edges verified)
  • README.md / README_zh-CN.md — document the new try/except/else/finally support with examples and a note that multiple statements in the try body are folded
  • setup.py / pyproject.toml — bump version to 0.6.0b1

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: cdfmlr <45259230+cdfmlr@users.noreply.github.com>
Copilot AI changed the title [WIP] Comment on stale and nonsense issues for resolution Add stale issue/PR management workflow Feb 28, 2026
… stale workflow

Co-authored-by: cdfmlr <45259230+cdfmlr@users.noreply.github.com>
Copilot AI changed the title Add stale issue/PR management workflow Add try/except/else/finally flowchart support Feb 28, 2026
@cdfmlr
Copy link
Copy Markdown
Owner

cdfmlr commented Feb 28, 2026

@copilot properly test the try/except/else/finally support. add complex and realistic cases including:

  • try with except and else and finally
  • do something -> try block -> other things
  • and try in a loop etc

Co-authored-by: cdfmlr <45259230+cdfmlr@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 28, 2026

@copilot properly test the try/except/else/finally support. add complex and realistic cases including:

  • try with except and else and finally
  • do something -> try block -> other t...

Added three new test cases in commit 5f64dbd:

  • test_try_full — all four clauses: two except handlers (including except Exception as e), an else clause, and finally; verifies every path (each handler's yes/no edge, the no-exception else path, and all tails converging into finally).
  • test_try_in_sequenceprepare() → try block → use(result): confirms the try node connects correctly when preceded and followed by other statements.
  • test_try_in_looptry/except nested inside a for loop: verifies the loop back-edges from both the handler body and the unhandled-exception path return to the loop condition.

…+ ZH)

Co-authored-by: cdfmlr <45259230+cdfmlr@users.noreply.github.com>
Copilot AI changed the title Add try/except/else/finally flowchart support Add try/except/else/finally flowchart support (Beta) Feb 28, 2026
…n for minimal try bodies

Co-authored-by: cdfmlr <45259230+cdfmlr@users.noreply.github.com>
Copilot AI changed the title Add try/except/else/finally flowchart support (Beta) Document try/except multi-line body behaviour + add test Feb 28, 2026
…tion scope

Co-authored-by: cdfmlr <45259230+cdfmlr@users.noreply.github.com>
Copilot AI changed the title Document try/except multi-line body behaviour + add test Fix try-body multi-statement exception scope bug; fold body into single node Feb 28, 2026
Copy link
Copy Markdown
Owner

@cdfmlr cdfmlr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot check it please.

# connect the *last* statement to the "exception raised?" diamond,
# leaving all preceding statements outside the exception-handling scope.
if len(ast_try.body) > 1:
body_text = '\n'.join(
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot join the lines manually? would it work properly with complex cases? for example, nested condition or loop statements. is this an existing pattern used in the existing code? it's ok to use it if it's an existing pattern or else it should be introduced more carefully.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, astunparse.unparse(stmt) handles complex statements correctly — it's a complete AST→source serialiser and produces valid multi-line output for nested if, for, while, etc. (tested above with both a nested if and a for loop inside the try body).

This is already the established pattern in the codebase: CommonOperation.__init__ does exactly OperationNode.__init__(self, operation=self.ast_to_source()) which is astunparse.unparse(self.ast_object).strip(), and it's the fallback used for any unrecognised statement including complex ones. The new code is just doing the same thing per-statement in the try body and joining the results — no new pattern is introduced.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 28, 2026

@copilot check it please.

All 27 tests pass. The folding logic uses astunparse.unparse — the same existing pattern used by CommonOperation throughout the codebase — so it handles complex nested statements (conditions, loops, etc.) correctly.

@cdfmlr cdfmlr marked this pull request as ready for review February 28, 2026 06:50
@cdfmlr cdfmlr changed the title Fix try-body multi-statement exception scope bug; fold body into single node Add try/except/else/finally flowchart support Feb 28, 2026
@cdfmlr
Copy link
Copy Markdown
Owner

cdfmlr commented Feb 28, 2026

@copilot bumping the version: v0.6.0b1 for this.

Co-authored-by: cdfmlr <45259230+cdfmlr@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 28, 2026

@copilot bumping the version: v0.6.0b1 for this.

Done in d4d0ffc — bumped version to 0.6.0b1 in both setup.py and pyproject.toml.

@cdfmlr
Copy link
Copy Markdown
Owner

cdfmlr commented Feb 28, 2026

@copilot rewrite the PR description to describe the what the PR finally done, that is ddding try/except/else/finally flowchart support...

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 28, 2026

@copilot rewrite the PR description to describe the what the PR finally done, that is ddding try/except/else/finally flowchart support...

Done — the PR description has been rewritten to lead with "Adds full try/except/else/finally flowchart support" and summarises the implementation, all test cases, doc updates, and the version bump.

@cdfmlr cdfmlr merged commit 9f3d96e into master Feb 28, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants